{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# UniversalPertubation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "import os\n",
    "import keras\n",
    "import numpy as np\n",
    "from art.attacks import UniversalPerturbation\n",
    "from art.classifiers import KerasClassifier\n",
    "\n",
    "np.set_printoptions(suppress=True) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.1 完成数据处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "_img_gen = keras.preprocessing.image.ImageDataGenerator()\n",
    "Data_Gen = keras.preprocessing.image.DirectoryIterator(directory = \"data/my_data\",\n",
    "                                                       image_data_generator = _img_gen,\n",
    "                                                       target_size = (224,224),\n",
    "                                                       color_mode = 'rgb',\n",
    "                                                       batch_size = 16,\n",
    "                                                       shuffle = True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.2 搭建Keras模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = keras.applications.MobileNetV2(include_top=False, weights=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = model.output\n",
    "x = keras.layers.GlobalAveragePooling2D()(x)\n",
    "predictions = keras.layers.Dense(2, activation='softmax')(x)\n",
    "my_model = keras.models.Model(inputs=model.input, outputs=predictions)\n",
    "my_model.compile(optimizer='rmsprop', loss='categorical_crossentropy',metrics=[\"accuracy\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "my_model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.3 训练图像分类模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_model.fit_generator(Data_Gen, epochs=50)\n",
    "my_model.save(\"model/UP_model.h5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "scrolled": true
   },
   "source": [
    "### CheckPoint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "my_model = keras.models.load_model(\"model/UP_model.h5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.4 准备测试用数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_x, test_y = Data_Gen.next()\n",
    "predictions = my_model.predict(test_x)\n",
    "accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(test_y, axis=1)) / len(test_y)\n",
    "print('Accuracy on benign test examples: {}%'.format(accuracy * 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.5 生成攻击数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "classifier = KerasClassifier(model=my_model,clip_values=(0., 255.))\n",
    "attack = UniversalPerturbation(classifier=classifier, delta=0.1)\n",
    "x_test_adv = attack.generate(x=test_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "predictions = my_model.predict(x_test_adv)\n",
    "accuracy = np.sum(np.argmax(predictions, axis=1) == np.argmax(test_y, axis=1)) / len(test_y)\n",
    "print('Accuracy on benign test examples: {}%'.format(accuracy * 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Step.4 观看折腾后的数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "adv_x = x_test_adv.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "plt.imshow(adv_x[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "plt.imshow(test_x[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.argmax(predictions, axis=1) == np.argmax(test_y, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_model.predict(test_x[6:7])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_model.predict(x_test_adv[6:7])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
